/* Detect-zoom * ----------- * Cross Browser Zoom and Pixel Ratio Detector * Version 1.0.4 | Apr 1 2013 * dual-licensed under the WTFPL and MIT license * Maintained by https://github/tombigel * Original developer https://github.com/yonran */ //AMD and CommonJS initialization copied from https://github.com/zohararad/audio5js (function (root, ns, factory) { "use strict"; if (typeof (module) !== 'undefined' && module.exports) { // CommonJS module.exports = factory(ns, root); } else if (typeof (define) === 'function' && define.amd) { // AMD define("factory", function () { return factory(ns, root); }); } else { root[ns] = factory(ns, root); } }(window, 'detectZoom', function () { /** * Use devicePixelRatio if supported by the browser * @return {Number} * @private */ var devicePixelRatio = function () { return window.devicePixelRatio || 1; }; /** * Fallback function to set default values * @return {Object} * @private */ var fallback = function () { return { zoom: 1, devicePxPerCssPx: 1 }; }; /** * IE 8 and 9: no trick needed! * TODO: Test on IE10 and Windows 8 RT * @return {Object} * @private **/ var ie8 = function () { var zoom = Math.round((screen.deviceXDPI / screen.logicalXDPI) * 100) / 100; return { zoom: zoom, devicePxPerCssPx: zoom * devicePixelRatio() }; }; /** * For IE10 we need to change our technique again... * thanks https://github.com/stefanvanburen * @return {Object} * @private */ var ie10 = function () { var zoom = Math.round((document.documentElement.offsetHeight / window.innerHeight) * 100) / 100; return { zoom: zoom, devicePxPerCssPx: zoom * devicePixelRatio() }; }; /** * Mobile WebKit * the trick: window.innerWIdth is in CSS pixels, while * screen.width and screen.height are in system pixels. * And there are no scrollbars to mess up the measurement. * @return {Object} * @private */ var webkitMobile = function () { var deviceWidth = (Math.abs(window.orientation) == 90) ? screen.height : screen.width; var zoom = deviceWidth / window.innerWidth; return { zoom: zoom, devicePxPerCssPx: zoom * devicePixelRatio() }; }; /** * Desktop Webkit * the trick: an element's clientHeight is in CSS pixels, while you can * set its line-height in system pixels using font-size and * -webkit-text-size-adjust:none. * device-pixel-ratio: http://www.webkit.org/blog/55/high-dpi-web-sites/ * * Previous trick (used before http://trac.webkit.org/changeset/100847): * documentElement.scrollWidth is in CSS pixels, while * document.width was in system pixels. Note that this is the * layout width of the document, which is slightly different from viewport * because document width does not include scrollbars and might be wider * due to big elements. * @return {Object} * @private */ var webkit = function () { var important = function (str) { return str.replace(/;/g, " !important;"); }; var div = document.createElement('div'); div.innerHTML = "1
2
3
4
5
6
7
8
9
0"; div.setAttribute('style', important('font: 100px/1em sans-serif; -webkit-text-size-adjust: none; text-size-adjust: none; height: auto; width: 1em; padding: 0; overflow: visible;')); // The container exists so that the div will be laid out in its own flow // while not impacting the layout, viewport size, or display of the // webpage as a whole. // Add !important and relevant CSS rule resets // so that other rules cannot affect the results. var container = document.createElement('div'); container.setAttribute('style', important('width:0; height:0; overflow:hidden; visibility:hidden; position: absolute;')); container.appendChild(div); document.body.appendChild(container); var zoom = 1000 / div.clientHeight; zoom = Math.round(zoom * 100) / 100; document.body.removeChild(container); return{ zoom: zoom, devicePxPerCssPx: zoom * devicePixelRatio() }; }; /** * no real trick; device-pixel-ratio is the ratio of device dpi / css dpi. * (Note that this is a different interpretation than Webkit's device * pixel ratio, which is the ratio device dpi / system dpi). * * Also, for Mozilla, there is no difference between the zoom factor and the device ratio. * * @return {Object} * @private */ var firefox4 = function () { var zoom = mediaQueryBinarySearch('min--moz-device-pixel-ratio', '', 0, 10, 20, 0.0001); zoom = Math.round(zoom * 100) / 100; return { zoom: zoom, devicePxPerCssPx: zoom }; }; /** * Firefox 18.x * Mozilla added support for devicePixelRatio to Firefox 18, * but it is affected by the zoom level, so, like in older * Firefox we can't tell if we are in zoom mode or in a device * with a different pixel ratio * @return {Object} * @private */ var firefox18 = function () { return { zoom: firefox4().zoom, devicePxPerCssPx: devicePixelRatio() }; }; /** * works starting Opera 11.11 * the trick: outerWidth is the viewport width including scrollbars in * system px, while innerWidth is the viewport width including scrollbars * in CSS px * @return {Object} * @private */ var opera11 = function () { var zoom = window.top.outerWidth / window.top.innerWidth; zoom = Math.round(zoom * 100) / 100; return { zoom: zoom, devicePxPerCssPx: zoom * devicePixelRatio() }; }; /** * Use a binary search through media queries to find zoom level in Firefox * @param property * @param unit * @param a * @param b * @param maxIter * @param epsilon * @return {Number} */ var mediaQueryBinarySearch = function (property, unit, a, b, maxIter, epsilon) { var matchMedia; var head, style, div; if (window.matchMedia) { matchMedia = window.matchMedia; } else { head = document.getElementsByTagName('head')[0]; style = document.createElement('style'); head.appendChild(style); div = document.createElement('div'); div.className = 'mediaQueryBinarySearch'; div.style.display = 'none'; document.body.appendChild(div); matchMedia = function (query) { style.sheet.insertRule('@media ' + query + '{.mediaQueryBinarySearch ' + '{text-decoration: underline} }', 0); var matched = getComputedStyle(div, null).textDecoration == 'underline'; style.sheet.deleteRule(0); return {matches: matched}; }; } var ratio = binarySearch(a, b, maxIter); if (div) { head.removeChild(style); document.body.removeChild(div); } return ratio; function binarySearch(a, b, maxIter) { var mid = (a + b) / 2; if (maxIter <= 0 || b - a < epsilon) { return mid; } var query = "(" + property + ":" + mid + unit + ")"; if (matchMedia(query).matches) { return binarySearch(mid, b, maxIter - 1); } else { return binarySearch(a, mid, maxIter - 1); } } }; /** * Generate detection function * @private */ var detectFunction = (function () { var func = fallback; //IE8+ if (!isNaN(screen.logicalXDPI) && !isNaN(screen.systemXDPI)) { func = ie8; } // IE10+ / Touch else if (window.navigator.msMaxTouchPoints) { func = ie10; } //Mobile Webkit else if ('orientation' in window && typeof document.body.style.webkitMarquee === 'string') { func = webkitMobile; } //WebKit else if (typeof document.body.style.webkitMarquee === 'string') { func = webkit; } //Opera else if (navigator.userAgent.indexOf('Opera') >= 0) { func = opera11; } //Last one is Firefox //FF 18.x else if (window.devicePixelRatio) { func = firefox18; } //FF 4.0 - 17.x else if (firefox4().zoom > 0.001) { func = firefox4; } return func; }()); return ({ /** * Ratios.zoom shorthand * @return {Number} Zoom level */ zoom: function () { return detectFunction().zoom; }, /** * Ratios.devicePxPerCssPx shorthand * @return {Number} devicePxPerCssPx level */ device: function () { return detectFunction().devicePxPerCssPx; } }); })); var wpcom_img_zoomer = { zoomed: false, timer: null, interval: 1000, // zoom polling interval in millisecond // Should we apply width/height attributes to control the image size? imgNeedsSizeAtts: function( img ) { // Do not overwrite existing width/height attributes. if ( img.getAttribute('width') !== null || img.getAttribute('height') !== null ) return false; // Do not apply the attributes if the image is already constrained by a parent element. if ( img.width < img.naturalWidth || img.height < img.naturalHeight ) return false; return true; }, init: function() { var t = this; try{ t.zoomImages(); t.timer = setInterval( function() { t.zoomImages(); }, t.interval ); } catch(e){ } }, stop: function() { if ( this.timer ) clearInterval( this.timer ); }, getScale: function() { var scale = detectZoom.device(); // Round up to 1.5 or the next integer below the cap. if ( scale <= 1.0 ) scale = 1.0; else if ( scale <= 1.5 ) scale = 1.5; else if ( scale <= 2.0 ) scale = 2.0; else if ( scale <= 3.0 ) scale = 3.0; else if ( scale <= 4.0 ) scale = 4.0; else scale = 5.0; return scale; }, shouldZoom: function( scale ) { var t = this; // Do not operate on hidden frames. if ( "innerWidth" in window && !window.innerWidth ) return false; // Don't do anything until scale > 1 if ( scale == 1.0 && t.zoomed == false ) return false; return true; }, zoomImages: function() { var t = this; var scale = t.getScale(); if ( ! t.shouldZoom( scale ) ){ return; } t.zoomed = true; // Loop through all the elements on the page. var imgs = document.getElementsByTagName("img"); for ( var i = 0; i < imgs.length; i++ ) { // Wait for original images to load if ( "complete" in imgs[i] && ! imgs[i].complete ) continue; // For browsers that support srcset and sizes attributes, // skip images that have them. if ( imgs[i].hasAttribute('srcset') && imgs[i].hasAttribute('sizes') && ( 'sizes' in imgs[i] ) ) { continue; } // Skip images that don't need processing. var imgScale = imgs[i].getAttribute("scale"); if ( imgScale == scale || imgScale == "0" ) continue; // Skip images that have already failed at this scale var scaleFail = imgs[i].getAttribute("scale-fail"); if ( scaleFail && scaleFail <= scale ) continue; // Skip images that have no dimensions yet. if ( ! ( imgs[i].width && imgs[i].height ) ) continue; // Skip images from Lazy Load plugins if ( ! imgScale && imgs[i].getAttribute("data-lazy-src") && (imgs[i].getAttribute("data-lazy-src") !== imgs[i].getAttribute("src"))) continue; if ( t.scaleImage( imgs[i], scale ) ) { // Mark the img as having been processed at this scale. imgs[i].setAttribute("scale", scale); } else { // Set the flag to skip this image. imgs[i].setAttribute("scale", "0"); } } }, scaleImage: function( img, scale ) { var t = this; var newSrc = img.src; // Skip slideshow images if ( img.parentNode.className.match(/slideshow-slide/) ) return false; // Scale gravatars that have ?s= or ?size= if ( img.src.match( /^https?:\/\/([^\/]*\.)?gravatar\.com\/.+[?&](s|size)=/ ) ) { newSrc = img.src.replace( /([?&](s|size)=)(\d+)/, function( $0, $1, $2, $3 ) { // Stash the original size var originalAtt = "originals", originalSize = img.getAttribute(originalAtt); if ( originalSize === null ) { originalSize = $3; img.setAttribute(originalAtt, originalSize); if ( t.imgNeedsSizeAtts( img ) ) { // Fix width and height attributes to rendered dimensions. img.width = img.width; img.height = img.height; } } // Get the width/height of the image in CSS pixels var size = img.clientWidth; // Convert CSS pixels to device pixels var targetSize = Math.ceil(img.clientWidth * scale); // Don't go smaller than the original size targetSize = Math.max( targetSize, originalSize ); // Don't go larger than the service supports targetSize = Math.min( targetSize, 512 ); return $1 + targetSize; }); } // Scale resize queries (*.files.wordpress.com) that have ?w= or ?h= else if ( img.src.match( /^https?:\/\/([^\/]+)\.files\.wordpress\.com\/.+[?&][wh]=/ ) ) { if ( img.src.match( /[?&]crop/ ) ) return false; var changedAttrs = {}; var matches = img.src.match( /([?&]([wh])=)(\d+)/g ); for ( var i = 0; i < matches.length; i++ ) { var lr = matches[i].split( '=' ); var thisAttr = lr[0].replace(/[?&]/g, '' ); var thisVal = lr[1]; // Stash the original size var originalAtt = 'original' + thisAttr, originalSize = img.getAttribute( originalAtt ); if ( originalSize === null ) { originalSize = thisVal; img.setAttribute(originalAtt, originalSize); if ( t.imgNeedsSizeAtts( img ) ) { // Fix width and height attributes to rendered dimensions. img.width = img.width; img.height = img.height; } } // Get the width/height of the image in CSS pixels var size = thisAttr == 'w' ? img.clientWidth : img.clientHeight; var naturalSize = ( thisAttr == 'w' ? img.naturalWidth : img.naturalHeight ); // Convert CSS pixels to device pixels var targetSize = Math.ceil(size * scale); // Don't go smaller than the original size targetSize = Math.max( targetSize, originalSize ); // Don't go bigger unless the current one is actually lacking if ( scale > img.getAttribute("scale") && targetSize <= naturalSize ) targetSize = thisVal; // Don't try to go bigger if the image is already smaller than was requested if ( naturalSize < thisVal ) targetSize = thisVal; if ( targetSize != thisVal ) changedAttrs[ thisAttr ] = targetSize; } var w = changedAttrs.w || false; var h = changedAttrs.h || false; if ( w ) { newSrc = img.src.replace(/([?&])w=\d+/g, function( $0, $1 ) { return $1 + 'w=' + w; }); } if ( h ) { newSrc = newSrc.replace(/([?&])h=\d+/g, function( $0, $1 ) { return $1 + 'h=' + h; }); } } // Scale mshots that have width else if ( img.src.match(/^https?:\/\/([^\/]+\.)*(wordpress|wp)\.com\/mshots\/.+[?&]w=\d+/) ) { newSrc = img.src.replace( /([?&]w=)(\d+)/, function($0, $1, $2) { // Stash the original size var originalAtt = 'originalw', originalSize = img.getAttribute(originalAtt); if ( originalSize === null ) { originalSize = $2; img.setAttribute(originalAtt, originalSize); if ( t.imgNeedsSizeAtts( img ) ) { // Fix width and height attributes to rendered dimensions. img.width = img.width; img.height = img.height; } } // Get the width of the image in CSS pixels var size = img.clientWidth; // Convert CSS pixels to device pixels var targetSize = Math.ceil(size * scale); // Don't go smaller than the original size targetSize = Math.max( targetSize, originalSize ); // Don't go bigger unless the current one is actually lacking if ( scale > img.getAttribute("scale") && targetSize <= img.naturalWidth ) targetSize = $2; if ( $2 != targetSize ) return $1 + targetSize; return $0; }); // Update height attribute to match width newSrc = newSrc.replace( /([?&]h=)(\d+)/, function($0, $1, $2) { if ( newSrc == img.src ) { return $0; } // Stash the original size var originalAtt = 'originalh', originalSize = img.getAttribute(originalAtt); if ( originalSize === null ) { originalSize = $2; img.setAttribute(originalAtt, originalSize); } // Get the height of the image in CSS pixels var size = img.clientHeight; // Convert CSS pixels to device pixels var targetSize = Math.ceil(size * scale); // Don't go smaller than the original size targetSize = Math.max( targetSize, originalSize ); // Don't go bigger unless the current one is actually lacking if ( scale > img.getAttribute("scale") && targetSize <= img.naturalHeight ) targetSize = $2; if ( $2 != targetSize ) return $1 + targetSize; return $0; }); } // Scale simple imgpress queries (s0.wp.com) that only specify w/h/fit else if ( img.src.match(/^https?:\/\/([^\/.]+\.)*(wp|wordpress)\.com\/imgpress\?(.+)/) ) { var imgpressSafeFunctions = ["zoom", "url", "h", "w", "fit", "filter", "brightness", "contrast", "colorize", "smooth", "unsharpmask"]; // Search the query string for unsupported functions. var qs = RegExp.$3.split('&'); for ( var q in qs ) { q = qs[q].split('=')[0]; if ( imgpressSafeFunctions.indexOf(q) == -1 ) { return false; } } // Fix width and height attributes to rendered dimensions. img.width = img.width; img.height = img.height; // Compute new src if ( scale == 1 ) newSrc = img.src.replace(/\?(zoom=[^&]+&)?/, '?'); else newSrc = img.src.replace(/\?(zoom=[^&]+&)?/, '?zoom=' + scale + '&'); } // Scale LaTeX images or Photon queries (i#.wp.com) else if ( img.src.match(/^https?:\/\/([^\/.]+\.)*(wp|wordpress)\.com\/latex\.php\?(latex|zoom)=(.+)/) || img.src.match(/^https?:\/\/i[\d]{1}\.wp\.com\/(.+)/) ) { // Fix width and height attributes to rendered dimensions. img.width = img.width; img.height = img.height; // Compute new src if ( scale == 1 ) { newSrc = img.src.replace(/\?(zoom=[^&]+&)?/, '?'); } else { newSrc = img.src; var url_var = newSrc.match( /\?w=(\d+)/ ); if ( url_var !== null && url_var[1] ) { newSrc = newSrc.replace( new RegExp( 'w=' + url_var[1] ), 'w=' + img.width ); } url_var = newSrc.match( /\?h=(\d+)/ ); if ( url_var !== null && url_var[1] ) { newSrc = newSrc.replace( new RegExp( 'h=' + url_var[1] ), 'h=' + img.height ); } var zoom_arg = '&zoom=2'; if ( !newSrc.match( /\?/ ) ) { zoom_arg = '?zoom=2'; } img.setAttribute( 'srcset', newSrc + zoom_arg + ' ' + scale + 'x' ); } } // Scale static assets that have a name matching *-1x.png or *@1x.png else if ( img.src.match(/^https?:\/\/[^\/]+\/.*[-@]([12])x\.(gif|jpeg|jpg|png)(\?|$)/) ) { // Fix width and height attributes to rendered dimensions. img.width = img.width; img.height = img.height; var currentSize = RegExp.$1, newSize = currentSize; if ( scale <= 1 ) newSize = 1; else newSize = 2; if ( currentSize != newSize ) newSrc = img.src.replace(/([-@])[12]x\.(gif|jpeg|jpg|png)(\?|$)/, '$1'+newSize+'x.$2$3'); } else { return false; } // Don't set img.src unless it has changed. This avoids unnecessary reloads. if ( newSrc != img.src ) { // Store the original img.src var prevSrc, origSrc = img.getAttribute("src-orig"); if ( !origSrc ) { origSrc = img.src; img.setAttribute("src-orig", origSrc); } // In case of error, revert img.src prevSrc = img.src; img.onerror = function(){ img.src = prevSrc; if ( img.getAttribute("scale-fail") < scale ) img.setAttribute("scale-fail", scale); img.onerror = null; }; // Finally load the new image img.src = newSrc; } return true; } }; wpcom_img_zoomer.init(); ; /* global pm, wpcom_reblog */ var jetpackLikesWidgetQueue = []; var jetpackLikesWidgetBatch = []; var jetpackLikesMasterReady = false; function JetpackLikespostMessage( message, target ) { if ( 'string' === typeof message ){ try { message = JSON.parse( message ); } catch(e) { return; } } pm( { target: target, type: 'likesMessage', data: message, origin: '*' } ); } function JetpackLikesBatchHandler() { var requests = []; jQuery( 'div.jetpack-likes-widget-unloaded' ).each( function() { if ( jetpackLikesWidgetBatch.indexOf( this.id ) > -1 ) { return; } jetpackLikesWidgetBatch.push( this.id ); var regex = /like-(post|comment)-wrapper-(\d+)-(\d+)-(\w+)/, match = regex.exec( this.id ), info; if ( ! match || match.length !== 5 ) { return; } info = { blog_id: match[2], width: this.width }; if ( 'post' === match[1] ) { info.post_id = match[3]; } else if ( 'comment' === match[1] ) { info.comment_id = match[3]; } info.obj_id = match[4]; requests.push( info ); }); if ( requests.length > 0 ) { JetpackLikespostMessage( { event: 'initialBatch', requests: requests }, window.frames['likes-master'] ); } } function JetpackLikesMessageListener( event, message ) { var allowedOrigin, $container, $list, offset, rowLength, height, scrollbarWidth; if ( 'undefined' === typeof event.event ) { return; } // We only allow messages from one origin allowedOrigin = window.location.protocol + '//widgets.wp.com'; if ( allowedOrigin !== message.origin ) { return; } if ( 'masterReady' === event.event ) { jQuery( document ).ready( function() { jetpackLikesMasterReady = true; var stylesData = { event: 'injectStyles' }, $sdTextColor = jQuery( '.sd-text-color' ), $sdLinkColor = jQuery( '.sd-link-color' ); if ( jQuery( 'iframe.admin-bar-likes-widget' ).length > 0 ) { JetpackLikespostMessage( { event: 'adminBarEnabled' }, window.frames[ 'likes-master' ] ); stylesData.adminBarStyles = { background: jQuery( '#wpadminbar .quicklinks li#wp-admin-bar-wpl-like > a' ).css( 'background' ), isRtl: ( 'rtl' === jQuery( '#wpadminbar' ).css( 'direction' ) ) }; } if ( ! window.addEventListener ) { jQuery( '#wp-admin-bar-admin-bar-likes-widget' ).hide(); } stylesData.textStyles = { color: $sdTextColor.css( 'color' ), fontFamily: $sdTextColor.css( 'font-family' ), fontSize: $sdTextColor.css( 'font-size' ), direction: $sdTextColor.css( 'direction' ), fontWeight: $sdTextColor.css( 'font-weight' ), fontStyle: $sdTextColor.css( 'font-style' ), textDecoration: $sdTextColor.css('text-decoration') }; stylesData.linkStyles = { color: $sdLinkColor.css('color'), fontFamily: $sdLinkColor.css('font-family'), fontSize: $sdLinkColor.css('font-size'), textDecoration: $sdLinkColor.css('text-decoration'), fontWeight: $sdLinkColor.css( 'font-weight' ), fontStyle: $sdLinkColor.css( 'font-style' ) }; JetpackLikespostMessage( stylesData, window.frames[ 'likes-master' ] ); JetpackLikesBatchHandler(); jQuery( document ).on( 'inview', 'div.jetpack-likes-widget-unloaded', function() { jetpackLikesWidgetQueue.push( this.id ); }); }); } if ( 'showLikeWidget' === event.event ) { jQuery( '#' + event.id + ' .post-likes-widget-placeholder' ).fadeOut( 'fast', function() { jQuery( '#' + event.id + ' .post-likes-widget' ).fadeIn( 'fast', function() { JetpackLikespostMessage( { event: 'likeWidgetDisplayed', blog_id: event.blog_id, post_id: event.post_id, obj_id: event.obj_id }, window.frames['likes-master'] ); }); }); } if ( 'clickReblogFlair' === event.event ) { wpcom_reblog.toggle_reblog_box_flair( event.obj_id ); } if ( 'showOtherGravatars' === event.event ) { $container = jQuery( '#likes-other-gravatars' ); $list = $container.find( 'ul' ); $container.hide(); $list.html( '' ); $container.find( '.likes-text span' ).text( event.total ); jQuery.each( event.likers, function( i, liker ) { var element = jQuery( '
  • ' ); element.addClass( liker.css_class ); element.find( 'a' ). attr({ href: liker.profile_URL, rel: 'nofollow', target: '_parent' }). addClass( 'wpl-liker' ); element.find( 'img' ). attr({ src: liker.avatar_URL, alt: liker.name }). css({ width: '30px', height: '30px', paddingRight: '3px' }); $list.append( element ); } ); offset = jQuery( '[name=\'' + event.parent + '\']' ).offset(); $container.css( 'left', offset.left + event.position.left - 10 + 'px' ); $container.css( 'top', offset.top + event.position.top - 33 + 'px' ); rowLength = Math.floor( event.width / 37 ); height = ( Math.ceil( event.likers.length / rowLength ) * 37 ) + 13; if ( height > 204 ) { height = 204; } $container.css( 'height', height + 'px' ); $container.css( 'width', rowLength * 37 - 7 + 'px' ); $list.css( 'width', rowLength * 37 + 'px' ); $container.fadeIn( 'slow' ); scrollbarWidth = $list[0].offsetWidth - $list[0].clientWidth; if ( scrollbarWidth > 0 ) { $container.width( $container.width() + scrollbarWidth ); $list.width( $list.width() + scrollbarWidth ); } } } pm.bind( 'likesMessage', JetpackLikesMessageListener ); jQuery( document ).click( function( e ) { var $container = jQuery( '#likes-other-gravatars' ); if ( $container.has( e.target ).length === 0 ) { $container.fadeOut( 'slow' ); } }); function JetpackLikesWidgetQueueHandler() { var $wrapper, wrapperID, found; if ( ! jetpackLikesMasterReady ) { setTimeout( JetpackLikesWidgetQueueHandler, 500 ); return; } if ( jetpackLikesWidgetQueue.length > 0 ) { // We may have a widget that needs creating now found = false; while( jetpackLikesWidgetQueue.length > 0 ) { // Grab the first member of the queue that isn't already loading. wrapperID = jetpackLikesWidgetQueue.splice( 0, 1 )[0]; if ( jQuery( '#' + wrapperID ).hasClass( 'jetpack-likes-widget-unloaded' ) ) { found = true; break; } } if ( ! found ) { setTimeout( JetpackLikesWidgetQueueHandler, 500 ); return; } } else if ( jQuery( 'div.jetpack-likes-widget-unloaded' ).length > 0 ) { // Grab any unloaded widgets for a batch request JetpackLikesBatchHandler(); // Get the next unloaded widget wrapperID = jQuery( 'div.jetpack-likes-widget-unloaded' ).first()[0].id; if ( ! wrapperID ) { // Everything is currently loaded setTimeout( JetpackLikesWidgetQueueHandler, 500 ); return; } } if ( 'undefined' === typeof wrapperID ) { setTimeout( JetpackLikesWidgetQueueHandler, 500 ); return; } $wrapper = jQuery( '#' + wrapperID ); $wrapper.find( 'iframe' ).remove(); if ( $wrapper.hasClass( 'slim-likes-widget' ) ) { $wrapper.find( '.post-likes-widget-placeholder' ).after( '' ); } else { $wrapper.find( '.post-likes-widget-placeholder' ).after( '' ); } $wrapper.removeClass( 'jetpack-likes-widget-unloaded' ).addClass( 'jetpack-likes-widget-loading' ); $wrapper.find( 'iframe' ).load( function( e ) { var $iframe = jQuery( e.target ); $wrapper.removeClass( 'jetpack-likes-widget-loading' ).addClass( 'jetpack-likes-widget-loaded' ); JetpackLikespostMessage( { event: 'loadLikeWidget', name: $iframe.attr( 'name' ), width: $iframe.width() }, window.frames[ 'likes-master' ] ); if ( $wrapper.hasClass( 'slim-likes-widget' ) ) { $wrapper.find( 'iframe' ).Jetpack( 'resizeable' ); } }); setTimeout( JetpackLikesWidgetQueueHandler, 250 ); } JetpackLikesWidgetQueueHandler(); ; /* global screen_reader_text */ /** * navigation.js * * Handles the navigation menu. */ ( function( $ ) { /* Define variables */ var header_wrapper, navigation_wrapper, site_navigation, classic_primary, classic_secondary, menu_toggle, window_width, menu_toggle_width, site_branding, header_search; header_wrapper = $( '.header-wrapper' ); navigation_wrapper = $( '.navigation-wrapper' ); site_navigation = $( '#site-navigation' ); classic_primary = $( '.navigation-classic .primary-navigation' ); classic_secondary = $( '.navigation-classic .secondary-navigation' ); menu_toggle = $( '.menu-toggle' ); site_branding = $( '.site-branding' ); header_search = $( '.header-search' ); /* Add dropdown toggle to Primary Navigation items */ $( '.primary-navigation .menu-primary > ul > .page_item_has_children > a, .primary-navigation .menu-primary > ul > .menu-item-has-children > a' ).after( '' ); /* Depending on window width */ function responsive_navigation() { var e = window, a = 'inner'; if ( ! ( 'innerWidth' in window ) ) { a = 'client'; e = document.documentElement || document.body; } window_width = e[ a+'Width' ]; menu_toggle_width = menu_toggle.outerWidth(); /* Reset menu_toggle DOM position */ if ( $( 'body' ).hasClass( 'rtl' ) ) { menu_toggle.appendTo( site_navigation ).css( 'margin-right', '' ); } else { menu_toggle.appendTo( site_navigation ).css( 'margin-left', '' ); } if ( window_width < 1020 ) { classic_secondary.appendTo( navigation_wrapper ); classic_primary.appendTo( navigation_wrapper ); } else { classic_secondary.insertBefore( header_wrapper ); classic_primary.insertAfter( header_wrapper ); } if ( window_width < 1230 ) { navigation_wrapper.insertBefore( header_wrapper ); if ( $( 'body' ).hasClass( 'rtl' ) ) { $( '.menu-secondary' ).css( 'padding-left', '' ); menu_toggle.css( 'margin-right', '' ); } else { $( '.menu-secondary' ).css( 'padding-right', '' ); menu_toggle.css( 'margin-left', '' ); } } else { navigation_wrapper.insertAfter( menu_toggle ); if ( $( 'body' ).hasClass( 'rtl' ) ) { $( '.navigation-default .menu-secondary' ).css( 'padding-left', menu_toggle_width + 60 ); } else { $( '.navigation-default .menu-secondary' ).css( 'padding-right', menu_toggle_width + 60 ); } if ( menu_toggle.hasClass( 'open' ) ) { $( 'html, body' ).css( 'overflow-y', 'hidden' ); menu_toggle.appendTo( navigation_wrapper ); if ( $( 'body' ).hasClass( 'rtl' ) ) { menu_toggle.css( 'margin-right', 930 / 2 - menu_toggle_width ); } else { menu_toggle.css( 'margin-left', 930 / 2 - menu_toggle_width ); } } else { $( 'html, body' ).css( 'overflow-y', '' ); if ( $( 'body' ).hasClass( 'rtl' ) ) { menu_toggle.css( 'margin-right', '' ); } else { menu_toggle.css( 'margin-left', '' ); } } } /* Add a max-width to .site-branding */ var gap_icons = 0; if ( site_navigation.length ) { gap_icons += 16; } if ( header_search.length ) { gap_icons += 16; } if ( window_width < 768 ) { site_branding.removeAttr( 'style' ); } else { site_branding.css( 'max-width', header_wrapper.outerWidth() - ( site_navigation.outerWidth() + header_search.outerWidth() + gap_icons ) ); } $( '.menu-primary .dropdown-toggle' ).each( function() { $( this ).css( 'top', $( this ).prev( 'a' ).outerHeight() - $( this ).outerHeight() - 1 ); } ); } /* Click toggle */ menu_toggle.click( function() { $( 'html, body' ).scrollTop( 0 ); $( this ).toggleClass( 'open' ); $( this ).attr( 'aria-expanded', $( this ).attr( 'aria-expanded' ) === 'false' ? 'true' : 'false' ); navigation_wrapper.toggle(); $( '.search-toggle' ).removeClass( 'open' ); $( '.search-toggle' ).attr( 'aria-expanded', 'false' ); $( '.search-wrapper' ).hide(); responsive_navigation(); } ); /* Load */ $( window ).load( responsive_navigation ).resize( responsive_navigation ); var container = $( '.navigation-classic .primary-navigation' ); // Fix child menus for touch devices. function fixMenuTouchTaps( container ) { var touchStartFn, parentLink = container.find( '.menu-item-has-children > a, .page_item_has_children > a' ); if ( 'ontouchstart' in window ) { touchStartFn = function( e ) { var menuItem = this.parentNode; if ( ! menuItem.classList.contains( 'focus' ) ) { e.preventDefault(); for( var i = 0; i < menuItem.parentNode.children.length; ++i ) { if ( menuItem === menuItem.parentNode.children[i] ) { continue; } menuItem.parentNode.children[i].classList.remove( 'focus' ); } menuItem.classList.add( 'focus' ); } else { menuItem.classList.remove( 'focus' ); } }; for ( var i = 0; i < parentLink.length; ++i ) { parentLink[i].addEventListener( 'touchstart', touchStartFn, false ) } } } fixMenuTouchTaps( container ); } )( jQuery ); ; ( function() { var is_webkit = navigator.userAgent.toLowerCase().indexOf( 'webkit' ) > -1, is_opera = navigator.userAgent.toLowerCase().indexOf( 'opera' ) > -1, is_ie = navigator.userAgent.toLowerCase().indexOf( 'msie' ) > -1; if ( ( is_webkit || is_opera || is_ie ) && document.getElementById && window.addEventListener ) { window.addEventListener( 'hashchange', function() { var element = document.getElementById( location.hash.substring( 1 ) ); if ( element ) { if ( ! /^(?:a|select|input|button|textarea)$/i.test( element.tagName ) ) { element.tabIndex = -1; } element.focus(); } }, false ); } })(); ; /* global screen_reader_text */ ( function( $ ) { /** * A function to add classes to body depending on window width. */ function body_class() { window_width = $( window ).width(); $( 'body' ).removeClass( 'small-screen medium-screen large-screen' ); if ( window_width >= 1020 ) { $( 'body' ).addClass( 'small-screen medium-screen large-screen' ); } else if ( window_width >= 768 ) { $( 'body' ).addClass( 'small-screen medium-screen' ); } else if ( window_width >= 600 ) { $( 'body' ).addClass( 'small-screen' ); } } $( window ).load( function() { body_class(); /* Add dropdown toggle to Custom Menus Widget items */ $( '.widget_nav_menu ul:not([id^="menu-social"]) .page_item_has_children > a, .widget_nav_menu ul:not([id^="menu-social"]) .menu-item-has-children > a' ).after( '' ); /* Toggle child menu items */ $( '.dropdown-toggle' ).click( function( e ) { e.preventDefault(); $( this ).toggleClass( 'toggle-on' ); $( this ).prev( 'a' ).toggleClass( 'toggle-on' ); $( this ).next( '.children, .sub-menu' ).toggleClass( 'toggle-on' ); $( this ).attr( 'aria-expanded', $( this ).attr( 'aria-expanded' ) === 'false' ? 'true' : 'false' ); $( this ).html( $( this ).html() === screen_reader_text.expand ? screen_reader_text.collapse : screen_reader_text.expand ) } ); } ).resize( body_class ); } )( jQuery ); ; var wpcom = window.wpcom || {}; wpcom.actionbar = {}; wpcom.actionbar.data = actionbardata; // This might be better in another file, but is here for now (function($){ var fbd = wpcom.actionbar.data, d = document, docHeight = $( d ).height(), b = d.getElementsByTagName( 'body' )[0], lastScrollTop = 0, lastScrollDir, fb, fhtml, fbhtml, slkhtml, followingbtn, followbtn, fbdf, action, slkhtml = '', foldhtml = '', reporthtml = '', customizeIcon, editIcon, themeHtml = '', signupHtml = '', loginHtml = '', viewReaderHtml = '', editSubsHtml = '', editFollowsHtml = '', toggleactionbar, $actionbar; // Don't show actionbar when iframed if ( window != window.top ) { return; } fhtml = ''; fbdf = d.createElement( 'div' ); fbdf.id = 'actionbar'; fbdf.innerHTML = fhtml; b.appendChild( fbdf ); $actionbar = $( '#actionbar' ).addClass( 'actnbr-' + fbd.themeSlug.replace( '/', '-' ) ); // Add classes based on contents if ( fbd.canCustomizeSite ) { $actionbar.addClass( 'actnbr-has-customize' ); } if ( fbd.canEditPost ) { $actionbar.addClass( 'actnbr-has-edit' ); } if ( ! fbd.canCustomizeSite ) { $actionbar.addClass( 'actnbr-has-follow' ); } if ( fbd.isFolded ) { $actionbar.addClass( 'actnbr-folded' ); } // Show status message if available if ( fbd.statusMessage ) { showActionBarStatusMessage( fbd.statusMessage ); } // *** Actions ***************** // Follow Site $actionbar.on( 'click', '.actnbr-actn-follow', function(e) { e.preventDefault(); if ( fbd.isLoggedIn ) { showActionBarStatusMessage( '
    ' + fbd.i18n.followedText + '
    ' ); bumpStat( 'followed' ); request( 'ab_subscribe_to_blog' ); } else { showActionBarFollowForm(); } } ) // UnFollow Site .on( 'click', '.actnbr-actn-following', function(e) { e.preventDefault(); $( '#actionbar .actnbr-actn-following' ).replaceWith( '' + followbtn + '' + fbd.i18n.follow + '' ); bumpStat( 'unfollowed' ); request( 'ab_unsubscribe_from_blog' ); } ) // Show shortlink prompt .on( 'click', '.actnbr-shortlink a', function(e) { e.preventDefault(); window.prompt( "Shortlink: ", fbd.shortlink ); } ) // Toggle more menu .on( 'click', '.actnbr-ellipsis', function(e) { if ( $( e.target ).closest( 'a' ).hasClass( 'actnbr-action' ) ) { return false; } var popoverLi = $( '#actionbar .actnbr-ellipsis' ); popoverLi.toggleClass( 'actnbr-hidden' ); setTimeout( function() { if ( ! popoverLi.hasClass( 'actnbr-hidden' ) ) { $( document ).on( 'click.actnbr-body-click', function(e) { popoverLi.addClass( 'actnbr-hidden' ); $( document ).off( 'click.actnbr-body-click' ); } ); } }, 10 ); }) // Fold/Unfold .on( 'click', '.actnbr-fold', function(e) { e.preventDefault(); if ( $( '#actionbar' ).hasClass( 'actnbr-folded' ) ) { $( '.actnbr-fold a' ).html( fbd.i18n.foldBar ); $( '#actionbar' ).removeClass( 'actnbr-folded' ); $.post( fbd.xhrURL, { 'action': 'unfold_actionbar' } ); } else { $( '.actnbr-fold a' ).html( fbd.i18n.unfoldBar ); $( '#actionbar' ).addClass( 'actnbr-folded' ); $.post( fbd.xhrURL, { 'action': 'fold_actionbar' } ); } }) // Record stats for clicks .on( 'click', '.actnbr-sitename a', function(e) { bumpStat( 'clicked_site_title' ); }) .on( 'click', '.actnbr-customize a', function(e) { bumpStat( 'customized' ); }) .on( 'click', '.actnbr-folded-customize a', function(e) { bumpStat( 'customized' ); }) .on( 'click', '.actnbr-theme a', function(e) { bumpStat( 'explored_theme' ); }) .on( 'click', '.actnbr-edit a', function(e) { bumpStat( 'edited' ); }) .on( 'click', '.flb-report a', function(e) { bumpStat( 'reported_content' ); }) .on( 'click', '.actnbr-follows a', function(e) { bumpStat( 'managed_following' ); }) .on( 'click', '.actnbr-shortlink a', function(e) { bumpStat( 'copied_shortlink' ); }) .on( 'click', '.actnbr-reader a', function(e) { bumpStat( 'view_reader' ); }) .on( 'submit', '.actnbr-follow-bubble form', function ( e ) { $( '#actionbar .actnbr-follow-bubble form button' ).attr( 'disabled', true ); }); // Make Follow/Unfollow requests var request = function( action ) { $.post( fbd.xhrURL, { 'action': action, '_wpnonce': fbd.nonce, 'source': 'actionbar', 'blog_id': fbd.siteID }); }; // Show/Hide actionbar on scroll fb = $('#actionbar'); toggleactionbar = function() { var st = $(window).scrollTop(), topOffset = 0; if ( $(window).scrollTop() < 0 ) { return; } // Still if ( lastScrollTop == 0 || ( ( st == lastScrollTop ) && lastScrollDir == 'up' ) ) { fb.removeClass( 'actnbr-hidden' ); // Moving } else { // Scrolling Up if ( st < lastScrollTop ){ fb.removeClass( 'actnbr-hidden' ); lastScrollDir = 'up'; // Scrolling Down } else { // check if there are any popovers open, and only hide action bar if not if ( $( '#actionbar > ul > li:not(.actnbr-hidden) > .actnbr-popover' ).length === 0 ) { fb.addClass( 'actnbr-hidden' ) lastScrollDir = 'down'; // Hide any menus $( '#actionbar li' ).addClass( 'actnbr-hidden' ); } } } lastScrollTop = st; } setInterval( toggleactionbar, 100 ); // Bump stats var bumpStat = function( stat ) { $.post( fbd.xhrURL, { 'action': 'actionbar_stats', 'stat': stat }); } function actionBarEscapeHtml(string) { return String(string).replace(/[&<>"'\/]/g, function (s) { var entityMap = { "&": "&", "<": "<", ">": ">", '"': '"', "'": ''', "/": '/' }; return entityMap[s]; }); }; function showActionBarStatusMessage( message ) { $( '#actionbar .actnbr-actn-follow' ).replaceWith( '' + followingbtn + '' + fbd.i18n.following + '' ); $( '#actionbar .actnbr-follow-bubble' ).html( ' \ \ '); var btn = $( '#actionbar .actnbr-btn' ); btn.removeClass( 'actnbr-hidden' ); setTimeout( function() { if ( ! btn.hasClass( 'actnbr-hidden' ) ) { $( '#actionbar .actnbr-email-field' ).focus(); $( document ).on( 'click.actnbr-body-click', function(e) { if ( $( e.target ).closest( '.actnbr-popover' )[0] ) { return; } btn.addClass( 'actnbr-hidden' ); $( document ).off( 'click.actnbr-body-click' ); } ); } }, 10 ); } function showActionBarFollowForm() { var btn = $( '#actionbar .actnbr-btn' ); btn.toggleClass( 'actnbr-hidden' ); var form = $('
    '); if ( fbd.i18n.followers ) form.append($('
    ').html(fbd.i18n.followers)); form.append($('
    ').append($('').attr({"type": "email", "name": "email", "placeholder": fbd.i18n.enterEmail, "class": "actnbr-email-field"}))); form.append($('')); form.append($('').attr('value', fbd.siteID)); form.append($('').attr('value', fbd.referer)); form.append($('')); form.append($(fbd.subscribeNonce)); form.append($('